/* * Copyright (c) 2012. HappyDroids LLC, All rights reserved. */ package com.happydroids.droidtowers; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetDescriptor; import com.badlogic.gdx.assets.AssetErrorListener; import com.badlogic.gdx.assets.AssetLoaderParameters; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.assets.loaders.*; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.Pools; import com.google.common.eventbus.EventBus; import com.happydroids.droidtowers.disk.FileResolverMultiplexer; import com.happydroids.droidtowers.events.AssetLoadCompleteEvent; import com.happydroids.droidtowers.events.AssetLoadErrorEvent; import com.happydroids.droidtowers.events.SafeEventBus; import java.util.HashMap; import java.util.Map; import static com.badlogic.gdx.assets.AssetLoaderParameters.LoadedCallback; public class MemoryTrackingAssetManager extends AssetManager { private int currentMemory; private Map<String, Integer> memoryPerFile; private final SafeEventBus eventBus; public MemoryTrackingAssetManager(FileResolverMultiplexer fileResolverMultiplexer) { super(fileResolverMultiplexer); currentMemory = 0; memoryPerFile = new HashMap<String, Integer>(); eventBus = new SafeEventBus(MemoryTrackingAssetManager.class.getSimpleName()); setErrorListener(new AssetErrorListener() { @Override public void error(AssetDescriptor asset, Throwable throwable) { AssetLoadErrorEvent event = Pools.obtain(AssetLoadErrorEvent.class); event.setFileName(asset.fileName); event.setType(asset.type); events().post(event); Pools.free(event); } }); } @SuppressWarnings("unchecked") private synchronized int calculateTextureSize(AssetManager assetManager, String fileName) { if (memoryPerFile.containsKey(fileName)) { return memoryPerFile.get(fileName); } Texture texture = assetManager.get(fileName, Texture.class); TextureData textureData = texture.getTextureData(); int textureSize = textureData.getWidth() * textureData.getHeight(); switch (textureData.getFormat()) { case RGB565: textureSize *= 2; break; case RGB888: textureSize *= 3; break; case RGBA4444: textureSize *= 2; break; case RGBA8888: textureSize *= 4; break; } if (textureData.useMipMaps()) { textureSize *= 1.33f; } memoryPerFile.put(fileName, textureSize); return textureSize; } @SuppressWarnings("unchecked") @Override public synchronized <T> void load(String fileName, Class<T> type, AssetLoaderParameters<T> parameter) { if (parameter == null) { parameter = makeAssetLoaderParameter(fileName, type); } if (parameter != null) { final LoadedCallback prevCallback = parameter.loadedCallback; parameter.loadedCallback = new LoadedCallback() { @Override public void finishedLoading(AssetManager assetManager, String fileName, Class type) { Gdx.app.log(MemoryTrackingAssetManager.class.getSimpleName(), "Loaded: " + fileName); if (type.equals(Texture.class)) { currentMemory += calculateTextureSize(assetManager, fileName); } if (prevCallback != null) { prevCallback.finishedLoading(assetManager, fileName, type); } AssetLoadCompleteEvent e = Pools.obtain(AssetLoadCompleteEvent.class); e.setFileName(fileName); e.setType(type); eventBus.post(e); Pools.free(e); } }; } super.load(fileName, type, parameter); } private <T> AssetLoaderParameters<T> makeAssetLoaderParameter(String fileName, Class<T> type) { AssetLoaderParameters<T> parameter; if (type.equals(Texture.class)) { parameter = (AssetLoaderParameters<T>) new TextureLoader.TextureParameter(); } else if (type.equals(TextureAtlas.class)) { parameter = (AssetLoaderParameters<T>) new TextureAtlasLoader.TextureAtlasParameter(); } else if (type.equals(Sound.class)) { parameter = (AssetLoaderParameters<T>) new SoundLoader.SoundParameter(); } else if (type.equals(BitmapFont.class)) { parameter = (AssetLoaderParameters<T>) new BitmapFontLoader.BitmapFontParameter(); } else if (type.equals(Pixmap.class)) { parameter = (AssetLoaderParameters<T>) new PixmapLoader.PixmapParameter(); } else if (type.equals(Music.class)) { parameter = (AssetLoaderParameters<T>) new MusicLoader.MusicParameter(); } else { parameter = null; } return parameter; } @Override public synchronized void unload(String fileName) { try { super.unload(fileName); if (memoryPerFile.containsKey(fileName)) { currentMemory -= memoryPerFile.get(fileName); } } catch (GdxRuntimeException ignored) { } } public synchronized float getMemoryInMegabytes() { return currentMemory / 1024f / 1024f; } public void invalidateAllTextures() { Texture.invalidateAllTextures(Gdx.app); finishLoading(); } public EventBus events() { return eventBus; } }